import json
from typing import TypedDict, Optional, List, Union, Dict, Any

from langchain_core.messages import HumanMessage, AIMessage
from pydantic import BaseModel
from typing_extensions import Annotated
from langgraph.graph import add_messages

class SessionState(TypedDict):
    """
    original_input: 用户输出的原始自然语言
    input_type: 需求分类判断节点的输出结果，有"requirement""issue"两个选项
    require_clearness：判断需求是否完整的输出结果，有"clear""not_clear"
    clarify_input: 用户澄清时输入的内容
    field_availability: 判断需求字段是否具备的结果，有"available""not_available"
    field_json: 持续维护的需求内所有字段的具备情况
    require_json: 持续维护的需求json
    process_solution: 大模型创建的涉及加工的加工方案，核心为一段文本，也可组织在json中
    collect_solution: 大模型创建的涉及采集的加工方案，核心为一段文本，也可组织在json中
    change_or_not: 用户是否修改不具备的字段
    """
    original_input: Optional[str]
    input_type:Optional[str]
    require_clearness:Optional[str]
    clarify_input:Optional[str]
    require_json:Optional[str]
    field_availability:Optional[dict]
    process_solution:Optional[str]
    collect_solution:Optional[str]
    change_or_not:Optional[str]
    next: Optional[str]  # 流程控制字段
    messages: Annotated[Union[HumanMessage,AIMessage],add_messages]
    user_initial_input: Optional[str]  # 存储初始用户输入
    missing_fields: Optional[dict]  # 缺失字段信息
    user_require:  Optional[List[str]]

    user_loop_count:Optional[int] #用户多次更新字段需求最大次数，暂定最大2次
    user_satisfaction_intention:Optional[str] #用户满意程度意图标识，0为不满意，1为满意
    user_update_fileds:Optional[str] #用于存储提取出来的字段信息


class CustomEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, (HumanMessage, AIMessage)):
            return obj.__dict__  # 假设这些对象的属性存储在__dict__中
        return super().default(obj)

# 定义请求和响应模型
class ChatRequest(BaseModel):
    thread_id: Optional[str] = None  # 可选，新会话可不提供
    user_input: str

# 定义请求和响应模型
class LogFileRequest(BaseModel):
    thread_id: Optional[str]   # 可选，新会话可不提供
    file_type: Optional[str]

# 定义请求和响应模型
class LogFileNumRequest(BaseModel):
    thread_id: str   # 可选，新会话可不提供
    file_number: int

class ChatResponse(BaseModel):
    thread_id: str
    assistant_response: str
    total_num:int
    is_complete: bool

class LogFileResponse(BaseModel):
    thread_id: str
    content: str

class LogFileNumResponse(BaseModel):
    thread_id: str
    line_number: int
    content: str

